<?php
//$Id: Core.php 522 2012-08-15 09:22:00Z tomqin@gmail.com $

/**
 * The Core Class
 *
 * @copyright   Copyright (C) 2010-2012 SupeFun.com Inc.
 * @author      TomQin <tomqin@gmail.com>
 * @license     http://www.supefun.com/license/
 */


//路径缩写
define('DS', DIRECTORY_SEPARATOR);

//系统路径
if(!defined('SYSTEM_ROOT')){
    exit('`SYSTEM_ROOT` is not defined!');
}

//调试信息
if(!defined('SYS_DEBUG')){
    define('SYS_DEBUG', false);
}

//系统开始时间
define('SYS_START_TIME', microtime(true));
define('TIMESTAMP', $_SERVER['REQUEST_TIME']);

//字符集
define('CHARSET', 'UTF-8');

//系统时区
date_default_timezone_set('Asia/Shanghai');

/**
 * 调试用函数，避免使用在发布版本中
 */
if(SYS_DEBUG == true){
    //设置错误信息
    error_reporting(E_ALL);

    function p($var, $name = ''){
        echo '<fieldset style="border:1px #333 dashed;margin:10px 0;">';
        if($name) echo "<legend><h3>$name</h3></legend>";
        echo '<pre>';
        empty($var) ? var_dump($var) : print_r($var);
        echo '</pre></fieldset>';
        echo "\n";
    }
}else{
    error_reporting(E_ALL ^ E_NOTICE);
}

Core::init();


/**
 * The Core Class
 *
 * @copyright   Copyright (C) 2010-2012 SupeFun.com Inc.
 * @author      TomQin <tomqin@gmail.com>
 * @license     http://www.supefun.com/license/
 */

final class Core{

    /**
     * 初始化操作，最先执行
     */
    public static function init(){

        //初始化配置信息
        self::initConfig();

        //初始化自动加载类方法
        self::$_classes = array(
            'Arr'     => self::getRealPath('LIB:Arr'),
            'App'     => self::getRealPath('LIB:App'),
            'Core'    => self::getRealPath('LIB:Core'),
            'View'    => self::getRealPath('LIB:View'),
            'Cache'   => self::getRealPath('LIB:Cache'),
            'Action'  => self::getRealPath('LIB:Action'),
            'Db'      => self::getRealPath('LIB:Data.Db'),
            'DbTable' => self::getRealPath('LIB:Data.DbTable'),
        );
        spl_autoload_register(array('Core', 'autoLoad'));

        //初始化数据库
        Db::initDb(self::getConfig('database.default'));
    }

    /**
     * 城市信息
     */
    public static function getDefaultCityInfo(){
        $cityid = intval(self::getCookie('SudingkeCityId'));

        $cityArray = self::getConfig('city.array');
        $defaultId = self::getConfig('default.cityid');

        return isset($cityArray[$cityid]) ? $cityArray[$cityid] : $cityArray[$defaultId];
    }

    /**
     * 应用程序
     */
    private static $_application;

    public static function instance($appname, $config = array()){
        $class = $appname.'App';
        if(!(self::$_application instanceof $class)){
            self::$_application = new $class;
        }
        return self::$_application;
    }

    public static function getApp(){
        return self::$_application;
    }

    /**
     * Cookie 设置
     */
    public static function getCookie($name, $default = null){
        return (isset($_COOKIE[$name]) && $_COOKIE[$name]) ? $_COOKIE[$name] : $default;
    }

    public static function setCookie($name, $value, $minutes = 0, $path = '/', $domain = null, $secure = false, $http_only = false){
        if (headers_sent()) return false;

        $time = ($minutes !== 0) ? $_SERVER['REQUEST_TIME'] + ($minutes * 60) : 0;
        if ($minutes < 0){
            unset($_COOKIE[$name]);
        }else{
            $_COOKIE[$name] = $value;
        }

        return setcookie($name, $value, $time, $path, $domain, $secure, $http_only);
    }

    /**
     * 配置设置
     */
    private static $_configs = array();

    public static function initConfig(){
        self::$_configs = require(SYSTEM_ROOT . 'data/config.inc.php');
    }

    public static function getConfig($name = '', $default = null){
        if(empty($name)){
            return self::$_configs;
        }else{
            return isset(self::$_configs[$name]) ? self::$_configs[$name] : $default;
        }
    }

    public static function setConfig($name, $value){
        self::$_configs[$name] = $value;
    }

    /**
     * 加载类
     */
    private static $_imports = array();
    private static $_classes = array();

    /**
     * 加载一个类或者加载一个包
     * 如果加载的包中有子文件夹不进行循环加载
     * 参数格式说明：'WIND:base.WFrontController'
     * WIND 注册的应用名称，应用名称与路径信息用‘:’号分隔
     * base.WFrontController 相对的路径信息
     * 如果不填写应用名称 ，例如‘base.WFrontController’，那么加载路径则相对于默认的应用路径
     *
     * 加载一个类的参数方式：'WIND:base.WFrontController'
     *
     * @param string $filepath | 文件路径信息 或者classname
     * @return string|null
     */
    public static function import($filepath) {
        if (!$filepath) return;
        if (isset(self::$_imports[$filepath])) return self::$_imports[$filepath];
        if (($pos = strrpos($filepath, '.')) !== false)
            $filename = substr($filepath, $pos + 1);
        elseif (($pos = strrpos($filepath, ':')) !== false)
            $filename = substr($filepath, $pos + 1);
        else
            $filename = $filepath;

        self::_setImport($filename, $filepath);
        return $filename;
    }

    private static function _setImport($classname, $classpath){
        self::$_imports[$classname] = $classpath;
        $classpath = self::getRealPath($classpath);

        self::$_classes[$classname] = $classpath;
        self::autoLoad($classname, $classpath);
    }

    /**
     * 类文件自动加载方法 callback
     * @param string $className
     * @param string $path
     * @return null
     */
    public static function autoLoad($class, $file = '') {
        if (class_exists($class))
            return;

        if ($file){
            $filename = $file;
        } elseif (isset(self::$_classes[$class])) {
            $filename = self::$_classes[$class];
        } else {
            $filename = $class . '.php';
        }

        if(is_file($filename))
            require_once($filename);
    }

    /**
     * 解析路径信息，并返回路径的详情
     * @param string $filepath 路径信息
     * @return string
     */
    public static function getRealPath($filepath, $ext = '.php') {
        if (false !== strpos($filepath, DIRECTORY_SEPARATOR)) return realpath($filepath);
        if (false !== ($pos = strpos($filepath, ':'))) {
            $namespace = self::getRootPath(substr($filepath, 0, $pos));
            $filepath = substr($filepath, $pos + 1);
        } else{
            $namespace = SYSTEM_ROOT;
        }
        $filepath = str_replace('.', '/', $filepath);
        $namespace && $filepath = $namespace . $filepath;
        return $filepath . $ext;
    }

    /**
     * 返回命名空间的路径信息
     * @param string $namespace
     * @return string
     */
    public static function getRootPath($alias) {
        $alias = strtoupper($alias);

        return isset(self::$_configs['namespace'][$alias]) ? self::$_configs['namespace'][$alias] : '';
    }

    public static function dump(){
        p(self::$_configs, 'CORE::_CONFIGS');
        p(self::$_imports, 'CORE::_IMPORTS');
        p(self::$_classes, 'CORE::_CLASSES');
    }

    /*

        loadClass('library', 'database.mysql');
        loadClass('base', 'mobile');
        loadClass('', 'srv/mobile/abc');
    */
    public static function loadClass($class, $auto = false, $init = array()){
        if($auto){
            /**
             * see http://www.phpeye.com/feedentry/viewen/id/9238
             */
            switch(count($init)) {
                case 0:
                  $object = new $class();break;
                case 1:
                  $object = new $class($init[0]);break;
                case 2:
                  $object = new $class($init[0],$init[1]);break;
                case 3:
                  $object = new $class($init[0],$init[1],$init[2]);break;
                case 4:
                  $object = new $class($init[0],$init[1],$init[2],$init[3]);break;
                default:
                  throw new Exception('Oops! Too many args, less than 4 args!');
             }
             //self::$objects[$class] = $object;
             return $object;
        }else{
            return true;
        }
    }
}

?>